<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        
        // 构造函数的书写 

        // 构造函数本质还是个函数  
        // 只不过 后来使用函数的时候  跟new 关键字一起用  
        
        // 注意事项:
        //  1.函数名跟普通函数尽量区别开来  首字母 大驼峰  
        //  内置构造函数  new Object  new Array  new String new RegExp  new Set new Map
        //  自定义构造函数也要这样 

        //  2. 构造函数不需要写return 
        //  如果写了return  返回一个基本数据类型 写了也白写 
        //  如果写了return 返回一个复杂数据类型  构造函数失效 不再创建对象
        //  而就变成了一个普通函数

        //  3. 必须跟new 关键字一起用 
        //  只有跟new 一起用 才能自动创建对象  并且自动返回对象 
        //  如果不跟new 一起用  就是个普通函数 


        // 4. 构造函数的this  
                // this-> 本次调用构造函数自动创建出来的那个对象
                // 自动创建出来的哪个对象   实例对象 
                // 我们管自动创建对象的过程叫 实例化  

        /* 
            普通函数 
                this->window
            对象函数
                this->对象本身
            定时器
                this-> window
            事件处理函数 
                this-> 事件源 
            箭头函数
                没有this 
                this -> 外部作用域的this 
        
        

                    // new 关键字做了什么?
                    // new 关键字 在堆内存开辟一个新的空间 
                     // this 指向这个新开辟的空间 
                    // 给新开空间的对象的属性赋值  
                    // obj1也指向新开辟的空间 

        
        */


        // function createPerson2(name,age,fn){
        //     // 自动创建1个空对象 

        //     this.name = name; // this代表的是本次创建的对象
        //     this.age = age;
        //     this.eat = fn;
        //     console.log(this);
        //     // 自动返回创建的这个对象  
        //     // return  123;   写了白写 
        //     // return  [1,2,3]; 构造函数失效 createPerson2变成一个普通函数

        // }

    //     var obj1 =  new createPerson2('张三',18,()=>{console.log('正在吃鸡');});
    //    var obj2 = new createPerson2('李四',19,()=>{console.log('正在吃面包');});
    //    var obj3 = new createPerson2('王五',20,()=>{console.log('正在吃火锅');});

    //     var obj1 = createPerson2('张三',18,()=>{console.log('正在吃鸡');});
    //    var obj2 = createPerson2('李四',19,()=>{console.log('正在吃面包');});
    //    var obj3 = createPerson2('王五',20,()=>{console.log('正在吃火锅');});

    //     console.log(obj1,obj2,obj3); // undefined undefined undefined




    // new 关键字到底经历了什么过程
    // 以下面为例 
    function createPerson2(name,age,fn){
            this.name = name;
            this.age = age;
            this.eat = fn;
        }
     var obj1 = new createPerson2('张三',18,()=>{console.log('正在吃鸡');});

    // new 关键字 在堆内存开辟一个新的空间 
    // this 指向这个新开辟的空间 
    // 给新开空间的对象的属性赋值  
    // obj1也指向新开辟的空间 

    console.log(obj1.name);
    console.log(obj1.age);
    obj1.eat()

    </script>
</body>
</html>